Imports System.Data
Imports System.Collections
Imports System.Collections.Generic
Imports Microsoft.VisualBasic
Imports System.Collections.Specialized
Imports System.Configuration.Provider

Public MustInherit Class ArticlesProvider : Inherits ProviderBase
    Private Shared _instance As ArticlesProvider = Nothing

    Public Sub New()

    End Sub

    ' methods that work with categories
    Public MustOverride Function GetCategories() As List(Of DataTypes.CategoryDetails)
    Public MustOverride Function GetCategoryByID(ByVal categoryID As String) As DataTypes.CategoryDetails
    Public MustOverride Function DeleteCategory(ByVal categoryID As String) As Boolean
    Public MustOverride Function UpdateCategory(ByVal category As DataTypes.CategoryDetails) As Boolean
    Public MustOverride Function InsertCategory(ByVal category As DataTypes.CategoryDetails) As String

    ' methods that work with articles
    Public MustOverride Function GetArticles(ByVal pageIndex As Integer, ByVal pageSize As Integer) As List(Of DataTypes.ArticleDetails)
    Public MustOverride Function GetArticles(ByVal categoryID As String, ByVal pageIndex As Integer, ByVal pageSize As Integer) As List(Of DataTypes.ArticleDetails)
    Public MustOverride Function GetArticleCount() As Integer
    Public MustOverride Function GetArticleCount(ByVal categoryID As String) As Integer
    Public MustOverride Function GetPublishedArticles(ByVal currentDate As DateTime, ByVal pageIndex As Integer, ByVal pageSize As Integer) As List(Of DataTypes.ArticleDetails)
    Public MustOverride Function GetPublishedArticles(ByVal categoryID As String, ByVal currentDate As DateTime, ByVal pageIndex As Integer, ByVal pageSize As Integer) As List(Of DataTypes.ArticleDetails)
    Public MustOverride Function GetPublishedArticleCount(ByVal currentDate As DateTime) As Integer
    Public MustOverride Function GetPublishedArticleCount(ByVal categoryID As String, ByVal currentDate As DateTime) As Integer
    Public MustOverride Function GetArticleByID(ByVal articleID As String) As DataTypes.ArticleDetails
    Public MustOverride Function DeleteArticle(ByVal articleID As String) As Boolean
    Public MustOverride Function UpdateArticle(ByVal article As DataTypes.ArticleDetails) As Boolean
    Public MustOverride Function InsertArticle(ByVal article As DataTypes.ArticleDetails) As String
    Public MustOverride Function ApproveArticle(ByVal articleID As String) As Boolean
    Public MustOverride Function IncrementArticleViewCount(ByVal articleID As String) As Boolean
    Public MustOverride Function RateArticle(ByVal articleID As String, ByVal rating As Integer) As Boolean
    Public MustOverride Function GetArticleBody(ByVal articleID As String) As String

    ' methods that work with comments
    Public MustOverride Function GetComments(ByVal pageIndex As Integer, ByVal pageSize As Integer) As List(Of DataTypes.CommentDetails)
    Public MustOverride Function GetComments(ByVal articleID As String, ByVal pageIndex As Integer, ByVal pageSize As Integer) As List(Of DataTypes.CommentDetails)
    Public MustOverride Function GetCommentCount() As Integer
    Public MustOverride Function GetCommentCount(ByVal articleID As String) As Integer
    Public MustOverride Function GetCommentByID(ByVal commentID As String) As DataTypes.CommentDetails
    Public MustOverride Function DeleteComment(ByVal commentID As String) As Boolean
    Public MustOverride Function UpdateComment(ByVal comment As DataTypes.CommentDetails) As Boolean
    Public MustOverride Function InsertComment(ByVal comment As DataTypes.CommentDetails) As String

    ' Returns a new CategoryDetails instance filled with the 
    ' DataReader's current record data
    Protected Overridable Function GetCategoryFromReader(ByVal reader As IDataReader) As DataTypes.CategoryDetails
        Dim returnVal As New DataTypes.CategoryDetails
        returnVal.CategoryId = reader("CategoryID").ToString
        returnVal.AddedDate = reader("AddedDate")
        returnVal.AddedBy = reader("AddedBy").ToString
        returnVal.Title = reader("Title").ToString
        returnVal.Importance = CInt(reader("Importance"))
        returnVal.Description = reader("Description").ToString
        returnVal.ImageURL = reader("ImageUrl").ToString
        Return returnVal
    End Function

    ' Returns a collection of CategoryDetails objects with 
    ' the data read from the input DataReader
    Protected Overridable Function GetCategoryCollectionFromReader(ByVal reader As IDataReader) As List(Of DataTypes.CategoryDetails)
        Dim categories As New List(Of DataTypes.CategoryDetails)
        While (reader.Read)
            categories.Add(GetCategoryFromReader(reader))
        End While
        Return categories
    End Function

    ' Returns a new ArticleDetails instance filled with the
    ' DataReader's current record data
    Protected Overridable Function GetArticlesFromReader(ByVal reader As IDataReader) As DataTypes.ArticleDetails
        Return GetArticleFromReader(reader, True)
    End Function

    Protected Overridable Function GetArticleFromReader(ByVal reader As IDataReader, ByVal readBody As Boolean) As DataTypes.ArticleDetails
        Dim article As New DataTypes.ArticleDetails(reader("articleID").ToString, _
            CType(reader("AddedDate"), DateTime), _
            reader("AddedBy").ToString, reader("CategoryID").ToString, _
            reader("CategoryTitle").ToString, reader("Title").ToString, _
            reader("Abstract").ToString, reader("Body").ToString, _
            reader("Country").ToString, _
            reader("State").ToString, _
            reader("City").ToString, _
            CType(reader("ReleaseDate"), DateTime), _
            CType(reader("ExpireDate"), DateTime), _
            CStringToBoolean(reader("Approved")), _
            CStringToBoolean(reader("Listed")), _
            CStringToBoolean(reader("CommentsEnabled")), _
            CStringToBoolean(reader("OnlyForMembers")), _
            CInt(reader("ViewCount")), _
            CInt(reader("Votes")), _
            CInt(reader("TotalRating")))
        If readBody Then
            article.Body = reader("Body").ToString
        End If

        Return article
    End Function

    ' Returns a collection of ArticleDetails objects with the 
    ' data read from the input DataReader
    Protected Overridable Function GetArticleCollectionFromReader( _
            ByVal reader As IDataReader) _
            As List(Of DataTypes.ArticleDetails)

        Return GetArticleCollectionFromReader(reader)
    End Function

    Protected Overridable Function GetArticleCollectionFromReader(ByVal reader As IDataReader, ByVal readBody As Boolean) As List(Of DataTypes.ArticleDetails)
        Dim articles As New List(Of DataTypes.ArticleDetails)
        While (reader.Read())
            articles.Add(GetArticleFromReader(reader, readBody))
        End While
        Return articles
    End Function

    ' Returns a new CommentDetails instance filled with the _
    ' DataReader's current record data
    Protected Overridable Function GetCommentFromReader(ByVal reader As IDataReader) As DataTypes.CommentDetails
        Dim comment As New DataTypes.CommentDetails(CInt(reader("CommentID")), _
            CDate(reader("AddedDate")), _
            reader("AddedBy").ToString, _
            reader("AddedByEmail").ToString, _
            reader("AddedByIP").ToString, _
            CInt(reader("ArticleID")), _
            reader("ArticleTitle").ToString, _
            reader("Body").ToString)
        Return comment
    End Function

    ' Returns a collection of CommentDetails objects with the data read from the input DataReader
    Protected Overridable Function GetCommentCollectionFromReader( _
            ByVal reader As IDataReader) _
            As List(Of DataTypes.CommentDetails)

        Dim comments As New List(Of DataTypes.CommentDetails)
        While (reader.Read)
            comments.Add(GetCommentFromReader(reader))
        End While
        Return comments
    End Function

    Private Function CStringToBoolean(ByVal input As String) As Boolean
        If input = "Y" Then
            Return True
        Else
            Return False
        End If
    End Function
End Class
